package lexer;


/**
 * Enumeration that provides the different sorts of Token
 * @author sebastian
 *
 */
public enum TokenType {
	// Special Tokens
	ERR("", false),
	EOF("", false),
	LIST("", false),

	// Separators
	RETURN("return", true),
	LBRACE("{", false),
	RBRACE("}", false),
	LPAREN("(", false),
	RPAREN(")", false),
	LSQBRAC("[", false),
	RSQBRAC("]", false),
	LARROWBRACKET("<", false),
	RARROWBRACKET(">", false),
	SEMI(";", false),
	COMMA(",", false),
	COLON(":", false),
	POINT(".", false),

	// While statement
	WHILE("while", true),

	// For statement
	FOR("for", true),
	
	// Switch statement
	SWITCH("switch", true),
	CASE("case", true),
	DEFAULT("default", true),
	
	// If statement
	IF("if", true),
	ELSE("else", true),
	
	// Literals and Identifiers
	IDENT("", false),
	INT_LITERAL("", false),
	DOUBLE_LITERAL("", false),
	CHAR_LITERAL("", false),
	TRUE_LITERAL("true", true),
	FALSE_LITERAL("false", true),
	LONG_LITERAL("", false),
	FLOAT_LITERAL("", false),
	NULL_LITERAL("null", true),
	STRING_LITERAL("", false),

	// Types
	CHAR_TYPE("char", true),
	DOUBLE_TYPE("double", true),
	INT_TYPE("int", true),
	LONG_TYPE("long", true),
	FLOAT_TYPE("float", true),
	BOOL_TYPE("boolean", true),
	VOID_TYPE("void", true),
	STRING_TYPE("string", true),

	// Variable Assignment
	ASSIGN("=", false),
	DIVIDEASSIGN("/=", false),
	MULASSIGN("*=", false),
	MODULOASSIGN("%=", false),
	PLUSASSIGN("+=", false),
	MINUSASSIGN("-=", false),
	SHIFTLEFTASSIGN("<<=", false),
	SHIFTRIGHTASSIGN(">>=", false),
	BITANDASSIGN("&=", false),
	BITORASSIGN("|=", false),
	BITXORASSIGN("^=", false),

	// Conditional Operator
	QMARK("?", false),

	// New Object
	NEW("new", true),
	CLASS("class", true),
	INTERFACE("interface", true),
	ENUM("enum", true),
	TEMPLATE("template", true),
	MAINCLASS("MainClass", true),
	EXTENDS("extends", true),
	IMPLEMENTS("implements", true),
	CONSTRUCT("construct", true),
	THIS("this", true),
	SUPER("super", true),
	HASDYNAMICTYPE("hasdynamictype", true),
	LENGTH("length", true),
	CAST("cast", true),
	
	// I/O
	OUT("out", true),
	IN("in", true),
	
	// Arithmetic & Logical operators
	NOT("!", false),
	MUL("*", false),
	DIVORSLASH("/", false),
	MOD("%", false),
	PLUS("+", false),
	MINUS("-", false),
	HOCH("^", false),
	SHL("<<", false),
	SHR(">>", false),
	LT("<", false),
	LE("<=", false),
	GT(">", false),
	GE(">=", false),
	EQ("==", false),
	NE("!=", false),
	BITAND("&", false),
	BITOR("|", false),
	AND("&&", false),
	OR("||", false),
	XOR("^^", false),
	INCREMENT("++", false),
	DECREMENT("--", false),
	
	//Modifiers
	PUBLIC("public", true),
	PRIVATE("private", true),
	PROTECTED("protected", true),
	CONST("const", true),
	STATIC("static", true),
	OVERRIDE("override", true),
	
	// Control Flow
	THROW("throw", true),
	THROWS("throws", true),
	BREAK("break", true),
	TRY("try", true),
	CATCH("catch", true),
	FINALLY("finally", true),
	
	// Code-Inlining
	LLVMSTART("llvm{", true),
	LLVMEND("}llvm", true),
	LLVMCODE("", false),
	LLVMDECLSTART("llvmdecl{", true),
	LLVMDECLEND("}llvmdecl", true),
	
	// Special
	NONE("none", true),
	IMPORT("import", true),
	AS("as", true),
	BACKSLASH("\\", false),
	GENERICSTART("<!", false),
	GENERICEND("!>", false)
	;

	/**
	 * The character representation of this token
	 */
	private final String text;

	/**
	 * true, if this token types text is a keyword
	 */
	private final boolean isKeyword;

	/**
	 * Creates a new token type for the given parameters.
	 *
	 * @param text      			The character representation of this token
	 * @param isKeyword  			true, if this token types text is a keyword
	 */
	private TokenType(String text, boolean isKeyword) {
		this.text = text;
		this.isKeyword = isKeyword;
	}

	/**
	 * Returns the character representation of this token type.
	 *
	 * @return {@link #text}
	 */
	public String getText() {
		return text;
	}

	/**
	 * String representation of this TokenType
	 * 
	 * @return a String representation of this TokenType
	 */
	public String toString() {
		return text.length() > 0 ? text : name();
	}

	/**
	 * Returns true, if this token types text is a keyword.
	 *
	 * @return {@link #isKeyword}
	 */
	public boolean isKeyword() {
		return isKeyword;
	}
}
